<--- %%NOBANNER%% --> resizec.sas
 BackForward

/*-------------------<-- Start of Description-->---------------------\
| Rebuild a data set, shortening all the character columns to minimum|
| space required;                                                    |
|---------------------<-- End of Description-->----------------------|
|--------------------------------------------------------------------|
|------------<-- Start of Files or Arguments Needed-->---------------|
| indata: an input data set;                                         |
| outdata: the output dataset;                                       |
| type: change the length or the format of the columns;              |
|-------------<-- End of Files or Arguments Needed-->----------------|
|--------------------------------------------------------------------|
|------------------<-- Start of Files Created-->---------------------|
| Usage: %resize(indata, outdata);                                   |
\-------------------<-- End of Files Created-->---------------------*/
%macro resizec/parmbuff;
/*--------------------------------------------\
| Author:   Duo Zhou;                         |
| Created:  10-15-2001 9:21pm;                |
| Modified: 12-25-2001 11:29am;               |
| Purpose:  Shortening all the character      |
|           columns / variable to minimum     |
|           length and format required;       |
\--------------------------------------------*/
%local inbuff outbuff linesize;
%let inbuff=%qscan(&syspbuff,1,%str((),));
%let outbuff=%qscan(&syspbuff,2,%str((),));
%let linesize = %SYSFUNC(GETOPTION(linesize));
%if (%index(%quote(&syspbuff),%quote(=))) %then %do;
   %if (%index(%quote(&inbuff),%quote(=))) %then %do;
      %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&inbuff))))),%quote(INDATA=))) %then %do;
         %let indata=%qscan(&inbuff,2,%str(=));
         %if (%index(%quote(&outbuff),%quote(=))) %then %do;
            %if (not %index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(OUTDATA=))) %then %do;
               %put ==> Alert! Keyword parameter "%qscan(&outbuff,1,%str(=))" is not defined!;
            %end;
            %else %do;
               %let outdata=%qscan(&outbuff,2,%str(=));
            %end;
         %end;
         %else %do;
            %let outdata=&outbuff;
         %end;
      %end;
      %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&inbuff))))),%quote(OUTDATA=))) %then %do;
         %let outdata=%qscan(&inbuff,2,%str(=));
         %if (%index(%quote(&outbuff),%quote(=))) %then %do;
            %if (not %index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(INDATA=))) %then %do;
               %put ==> Alert! Keyword parameter "%qscan(&outbuff,1,%str(=))" is not defined!;
            %end;
            %else %do;
               %let indata=%qscan(&outbuff,2,%str(=));
            %end;
         %end;
         %else %do;
            %let indata=&outbuff;
         %end;
      %end;
      %else %put ==> Alert! Keyword parameter "%qscan(&inbuff,1,%str(=))" is not defined!;
   %end;
   %else %if (%index(%quote(&outbuff),%quote(=))) %then %do;
      %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(INDATA=))) %then %do;
         %let indata=%qscan(&outbuff,2,%str(=));
         %let outdata=&inbuff;
      %end;
      %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&outbuff))))),%quote(OUTDATA=))) %then %do;
         %let indata=&inbuff;
         %let outdata=%qscan(&outbuff,2,%str(=));
      %end;
      %else %do;
         %put ==> Alert! Keyword parameter "%qscan(&outbuff,1,%str(=))" is not defined!;
      %end;
   %end;
%end;
%else %do;
   %let indata=&inbuff;
   %let outdata=&outbuff;
%end;
%local _oriord_;
%if (%quote(&indata) eq) %then %do;
  %put ==> Alert! No input data set is to be resized!;
  %goto ByeBye;
%end;
%if (%quote(&outdata) eq) %then %do;
   %let outdata=&indata;
%end;
proc contents noprint data=&indata out=_contnt_(index=(varnum));
run;
proc sql noprint;
   select name into : _oriord_ separated by ' '
   from _contnt_
   order by varnum;
quit;
%local dsid nobs rc;
%let dsid=%sysfunc(open(_contnt_));
%if &dsid %then %do;
  %let nobs=%sysfunc(attrn(&dsid,NOBS));
  %let rc=%sysfunc(close(&dsid));
%end;
%else %goto ByeBye;

%local zero;
%do _i_=1 %to &nobs;
  %local var&_i_ typ&_i_ len&_i_ mln&_i_;
%end;

data _null_;
  set _contnt_;
  call symput ('var'||left(_n_), name);
  if type=2
    then call symput ('typ'||left(_n_), '$');
    else call symput ('typ'||left(_n_), ' ');
  call symput ('len'||left(_n_), length);
run;

proc sql noprint;
  drop table _contnt_;

  select
  0
  %do _i_=1 %to &nobs;
    %if &&typ&_i_=$ %then ,max(length(&&var&_i_)) ;
  %end;
  into
  :zero
  %do _i_=1 %to &nobs;
    %if &&typ&_i_=$ %then ,:mln&_i_ ;
  %end;
  from &indata;
quit;

data &outdata;
  retain &_oriord_;
  length %do _i_=1 %to &nobs;
            %if &&typ&_i_=$ %then %do; &&var&_i_ $ &&mln&_i_ %end;
         %end;;
  format %do _i_=1 %to &nobs;
            %if &&typ&_i_=$ %then %do; &&var&_i_ $ &&mln&_i_... %end;
         %end;;
  set &indata;
run;
%ByeBye:
%mend resizec;